/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2021-2021. All rights reserved.
 */

package com.huawei.rpc.client.network.handler;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.CountDownLatch;

/**
 * @Author Lijl
 * @ClassName SendHandler
 * @Description 发送处理类，定义Netty入站处理
 * @Date 2022/2/14 16:53
 * @Version 1.0
 */
@Slf4j
public class SendHandler extends ChannelInboundHandlerAdapter {

    private CountDownLatch cdl;
    private Object readMsg = null;
    private byte[] data;

    public SendHandler(byte[] data){
        this.cdl = new CountDownLatch(1);
        this.data = data;
    }

    /**
     * @Author lijl
     * @MethodName channelActive
     * @Description 当连接服务段成功后，发送请求数据
     * @Date 16:56 2022/2/14
     * @Version 1.0
     * @param ctx 通道上下文
     * @return: void
    **/
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        log.info("Successful connection to server: {}",ctx);
        ByteBuf buffer = Unpooled.buffer(data.length);
        buffer.writeBytes(data);
        log.info("Client sends message: {}",buffer);
        ctx.writeAndFlush(buffer);
    }

    /**
     * @Author lijl
     * @MethodName channelRead
     * @Description 读取数据，数据读取完毕释放CD锁
     * @Date 16:59 2022/2/14
     * @Version 1.0
     * @param ctx 上下文
     * @param msg 字节流
     * @return: void
    **/
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        log.info("Client reads message: {}",msg);
        ByteBuf msgBuf = (ByteBuf) msg;
        byte[] resp = new byte[msgBuf.readableBytes()];
        msgBuf.readBytes(resp);
        readMsg = resp;
        cdl.countDown();
    }

    /**
     * @Author lijl
     * @MethodName rspData
     * @Description 等待读取数据完成
     * @Date 17:02 2022/2/14
     * @Version 1.0
     * @param
     * @return: java.lang.Object
    **/
    public Object rspData() throws InterruptedException {
        cdl.await();
        return readMsg;
    }

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        ctx.flush();
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        cause.printStackTrace();
        log.error("Exception occurred: {}",cause.getMessage());
        ctx.close();
    }
}
